package com.pdool.room.fight;

import com.pdool.common.constants.MsgId;
import com.pdool.common.dict.AreaEffectVo;
import com.pdool.common.dict.CardEffectVo;
import com.pdool.common.dto.FightResultDto;
import com.pdool.common.msg.fight.*;
import com.pdool.room.context.RoleFightInfo;
import com.pdool.room.context.RoomContext;
import com.pdool.room.dict.AreaEffectConfig;
import com.pdool.room.dict.CardEffectConfig;
import com.pdool.room.enums.EffectCreatorType;
import com.pdool.room.fight.area.FightAreaInfo;
import com.pdool.room.fight.effect.CardFightVo;
import com.pdool.room.fight.effect.EffectFightVo;
import com.pdool.room.mgr.RoomMgr;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class FightUtil {
    static FightUtil instance;
    @Autowired
    AreaEffectConfig areaEffectConfig;
    @Autowired
    CardEffectConfig cardEffectConfig;

    public FightUtil() {
        instance = this;
    }

    public static FightUtil getInstance() {
        return instance;
    }

    public void resetTmpFight(RoomContext roomContext) {
        for (RoleFightInfo value : roomContext.getMemberMap().values()) {
            for (FightAreaInfo fightAreaInfo : value.getAreaInfoList()) {
                fightAreaInfo.setTmpFight(0L);
                fightAreaInfo.getCardList().forEach(e -> e.setTmpFight(0));
            }
        }
    }

    public void pushHandCardChange(long roleId, List<CardFightVo> cardList) {
        HandCardAddSTC.Builder builder = HandCardAddSTC.newBuilder();
        builder.setRoleId(roleId);
        for (CardFightVo cardFightVo : cardList) {
            HandCardAddSTC.HandCardInfo.Builder builder1 = HandCardAddSTC.HandCardInfo.newBuilder();
            builder1.setCardId(cardFightVo.getCardId());
            builder1.setCost(builder1.getCost());
            builder.addHandCard(builder1);
        }

        RoomMgr.getInstance().sendMsg2Client(roleId, MsgId.PUSH_HAND_CARD_ADD, builder.build());
    }


    public void pushEnergy(RoleFightInfo roleFightInfo) {
        EnergyChange.Builder builder = EnergyChange.newBuilder();
        builder.setAddEnergy(roleFightInfo.getAddEnergy());
        builder.setRoundEnergy(roleFightInfo.getRoundEnergy());
        RoomMgr.getInstance().sendMsg2Client(roleFightInfo.getRoleId(), MsgId.PUSH_ENERGY_CHANGE, builder.build());

    }


    public void showCard(RoomContext roomContext) {
        ShowCardSTC.Builder builder = ShowCardSTC.newBuilder();

        for (RoleFightInfo value : roomContext.getMemberMap().values()) {
            List<CardFightVo> lastCardFightVo = value.getLastCardFightVo();
            if (lastCardFightVo.size() == 0) {
                continue;
            }
            lastCardFightVo.forEach(e -> {
                ShowCardSTC.CardInfo.Builder innerBuilder = ShowCardSTC.CardInfo.newBuilder();
                innerBuilder.setOwnerId(e.getRoleId());
                innerBuilder.setAreaId(e.getAreaId());
                innerBuilder.setCardId(e.getCardId());
                builder.addCardInfo(innerBuilder);
            });
            for (FightAreaInfo fightAreaInfo : value.getAreaInfoList()) {
                ActionUtil.getInstance().calcAreaFight(fightAreaInfo.getRoleId(), fightAreaInfo.getAreaId(), roomContext);
            }
        }
        RoomMgr.getInstance().sendMsg2Room(roomContext, MsgId.PUSH_SHOW_CARD, builder.build());
    }

    /**
     * 激活区域效果
     *
     * @param roomContext
     */
    public void activeZoneEffect(RoomContext roomContext) {
        int round = roomContext.getCurRound();

        List<Integer> areaInfo = roomContext.getCreateRoomInfo().getAreaInfo();
        if (round > areaInfo.size()) {
            return;
        }
        int areaConfigId = areaInfo.get(round - 1);

        ActiveAreaEffectSTC.Builder builder = ActiveAreaEffectSTC.newBuilder();

        AreaEffectVo byKey = areaEffectConfig.getByKey(areaConfigId);
        if (byKey.getEffectId() != null) {
            int effectId = byKey.getEffectId();
            CardEffectVo byKey1 = cardEffectConfig.getByKey(effectId);
            EffectFightVo effectFightVo = new EffectFightVo(byKey1);
            log.error("------->  effectId {}  areaConfigId  {}", effectId, areaConfigId);
            effectFightVo.setType(EffectCreatorType.AREA);
            effectFightVo.setAreaId(round - 1);
            roomContext.getAreaEffectList().add(effectFightVo);
            builder.setEffectId(byKey.getEffectId());
        }

        builder.setAreaId(round - 1);
        builder.setAreaConfigId(areaConfigId);
        RoomMgr.getInstance().sendMsg2Room(roomContext, MsgId.ACTIVE_AREA_EFFECT, builder.build());

    }

    public void pushStartRound(RoomContext roomContext) {

        StartRoundSTC.Builder builder = StartRoundSTC.newBuilder();
        builder.setRound(roomContext.getCurRound());
        builder.setMaxRound(roomContext.getMaxRound());
        builder.setLeftSec(roomContext.getLeftSec());

        RoomMgr.getInstance().sendMsg2Room(roomContext, MsgId.START_ROUND, builder.build());

    }

    public void pushCardFight(RoomContext roomContext, CardFightVo cardFightVo) {

        CardFightInfoSTC.Builder builder = CardFightInfoSTC.newBuilder();

        builder.setOwnerId(cardFightVo.getRoleId());
        builder.setAreaId(cardFightVo.getAreaId());
        builder.setCardId(cardFightVo.getCardId());
        builder.setFight(cardFightVo.getFight() + cardFightVo.getTmpFight());
        builder.setCost(cardFightVo.getCost());
        builder.setIsFake(cardFightVo.isFakeCard());
        builder.setIsValid(cardFightVo.isValid());

        RoomMgr.getInstance().sendMsg2Room(roomContext, MsgId.PUSH_CARD_FIGHT_INFO, builder.build());

    }

    //  结算战斗
    public void endFight(RoomContext roomContext) {

        Map<Integer, Long> roleFightMap = new HashMap<>();
        MultiValueMap<Integer, Long> posMap = new LinkedMultiValueMap<>();
        for (RoleFightInfo value : roomContext.getMemberMap().values()) {
            long sumFight = 0L;
            List<FightAreaInfo> areaInfoList = value.getAreaInfoList();

            for (FightAreaInfo fightAreaInfo : areaInfoList) {
                sumFight += fightAreaInfo.getSumFight();
            }
            Long orDefault = roleFightMap.getOrDefault(value.getPos(), 0L);
            roleFightMap.put(value.getPos(), orDefault + sumFight);

            posMap.add(value.getPos(), value.getRoleId());
        }
        long left = roleFightMap.get(0);
        long right = roleFightMap.get(1);
        int winnerPos = -1;
        int losePos = -1;
        //  总战力相等
        if (left != right) {
            if (left > right) {
                //  左边获胜
                winnerPos = 0;
                losePos = 1;
            } else {// 右边获胜
                winnerPos = 1;
                losePos = 0;
            }
        }

        FightResultDto fightResultDto = new FightResultDto();
        fightResultDto.setRoomId(roomContext.getRoomId());
        fightResultDto.setRoleList(new ArrayList<>(roomContext.getMemberMap().keySet()));
        if (winnerPos != -1) {
            List<Long> winnerList = posMap.getOrDefault(winnerPos, new ArrayList<>());
            List<Long> loseList = posMap.getOrDefault(losePos, new ArrayList<>());

            fightResultDto.getWinnerSet().addAll(winnerList);
            fightResultDto.getLoserSet().addAll(loseList);
        }

        fightResultDto.setReason(0);
        RoomMgr.getInstance().getGameService().trans2Game(fightResultDto);

        RoomMgr.getInstance().stopActor(roomContext.getRoomId());
    }

}
